package org.light.domain;

import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

import org.light.core.Verb;
import org.light.exception.ValidateException;
import org.light.generator.NamedUtilMethodGenerator;
import org.light.utils.InterVarUtil;
import org.light.utils.StringUtil;

public class LoginController extends Controller {
	private static final long serialVersionUID = 229666513964270905L;
	protected Verb verb;
	protected Domain domain;
	protected Set<Service> otherServices = new TreeSet<>();
	
	public Verb getVerb() {
		return verb;
	}

	public void setVerb(Verb verb) {
		this.verb = verb;
	}

	public Domain getDomain() {
		return domain;
	}

	public void setDomain(Domain domain) {
		this.domain = domain;
	}

	public Set<Service> getOtherServices() {
		return otherServices;
	}

	public void setOtherServices(Set<Service> otherServices) {
		this.otherServices = otherServices;
	}

	public void addOtherService(Service otheService){
		this.otherServices.add(otheService);
	}

	public String generateControllerString()  throws Exception{
		this.verb.setDomain(domain);
		if (this.verb.generateControllerMethod() == null) return null;
		//Method verbMethod = this.verb.generateFacadeMethod();
		//this.addMethod(verbMethod);
		StringBuilder sb = new StringBuilder();
		if (this.domain.getPackageToken() !=null && !"".equalsIgnoreCase(this.domain.getPackageToken())) sb.append("package ").append(this.domain.getPackageToken()).append(".").append(this.domain.getControllerSuffix()).append(";\n\n");
		Set<String> imports = this.generateImportStrings();
		for (String s: imports){
			sb.append("import ").append(s).append(";\n");
		}
		sb.append("import javax.servlet.annotation.WebServlet;\n");
		sb.append("\n");
		sb.append("@WebServlet(name = \""+StringUtil.lowerFirst(this.getStandardName())+"\",urlPatterns = \"/login"+ this.domain.getControllerNamingSuffix()+"/"+StringUtil.lowerFirst(this.verb.getVerbName())+"\")\n");
		sb.append("public class ").append(this.getStandardName()).append(" extends HttpServlet{\n");		
		
		//generate fields notions
		Iterator it = this.getFields().iterator();
		  while (it.hasNext()) {	
		        Field field = (Field) it.next();
		        String fieldName = field.getFieldName();
		        String fieldType = field.getFieldType();
		        sb.append("\tprotected ").append(fieldType).append(" ").append(fieldName).append(";\n");
	        }
		  sb.append("\n");
		  //generate getter setter notions
		  it = this.getFields().iterator();
		  while (it.hasNext()) {	
		        Field field = (Field) it.next();
		        String fieldName = field.getFieldName();
		        String fieldType = field.getFieldType();
		        // generate setters
		        sb.append("\tpublic void set").append(StringUtil.capFirst(fieldName)).append("(").append(fieldType).append(" ").append(StringUtil.lowerFirst(fieldName)).append("){\n");
		        sb.append("\t\tthis.").append(StringUtil.lowerFirst(fieldName)).append(" = ").append(StringUtil.lowerFirst(fieldName)).append(";\n");
		        sb.append("\t}\n\n");
		        // generate getters
		        sb.append("\tpublic ").append(fieldType).append(" get").append(StringUtil.capFirst(fieldName)).append("(){;\n");
		        sb.append("\t\treturn this.").append(StringUtil.lowerFirst(fieldName)).append(";\n");
		        sb.append("\t}\n\n");
	        }

			for (Service service:this.otherServices){
				sb.append("\tprotected ").append(service.getStandardName()).append(" ").append(StringUtil.lowerFirst(service.getStandardName())).append(" = new ").append(service.getStandardName()).append("Impl();\n");
			}

			Iterator it2 = this.getMethods().iterator();
			while (it2.hasNext()){
				sb.append(((Method)it2.next()).generateMethodString()).append("\n");
			}
			sb.append("}\n");
			return sb.toString();
	}

	public LoginController(Verb  verb, Domain domain) throws Exception{
		super();
		verb.setDomain(domain);
		this.verb = verb;
		this.domain = domain;
		this.standardName = verb.getVerbName() + domain.getControllerNamingSuffix();
		
		ValidateInfo info = this.validate();
		if (info.success){
			try {
				Method processRequest = this.verb.generateControllerMethod();
				Method doGet = NamedUtilMethodGenerator.generateServletDoGetCallProcessRequestMethod(2, InterVarUtil.Servlet.request, InterVarUtil.Servlet.response);
				Method doPost =  NamedUtilMethodGenerator.generateServletDoPostCallProcessRequestMethod(2, InterVarUtil.Servlet.request, InterVarUtil.Servlet.response);
				Method servletInfo = NamedUtilMethodGenerator.generateGetServletInfoMethod(2, "Powered by Mind Rules.");
				this.addMethod(processRequest);
				this.addMethod(servletInfo);
				this.addMethod(doGet);
				this.addMethod(doPost);
			} catch(Exception e) {
				e.printStackTrace();
			}
		}else {
			ValidateException e = new ValidateException(info);
			throw e;
		}
	}
	
	public LoginController(){super();}

	@Override
	public int compareTo(Controller o) {
		String myName = this.getStandardName();
		String otherName = o.getStandardName();
		return myName.compareTo(otherName);
	}
}
